package com.lyl.activiti.demo.web.controller;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lyl.activiti.demo.bean.BusinessInfo;
import com.lyl.activiti.demo.bean.BusinessInfoExample;
import com.lyl.activiti.demo.bean.Leave;
import com.lyl.activiti.demo.bpm.cmd.HistoryProcessInstanceDiagramCmd;
import com.lyl.activiti.demo.bpm.cmd.WithdrawTaskCmd;
import com.lyl.activiti.demo.mapper.BusinessInfoMapper;
import com.lyl.activiti.demo.mapper.CustomMapper;
import com.lyl.activiti.demo.mapper.LeaveMapper;

/**
 * 
 * @author lijj
 * 
 */

@Controller
@RequestMapping(value = "/workflow")
public class WorkflowController extends BaseController {

	@Autowired
	LeaveMapper leaveMapper;
	@Autowired
	CustomMapper customMapper;
	@Autowired
	BusinessInfoMapper businessInfoMapper;

	private static final String BUSINESS_INFO_DEFINITION_KEY = "businessinfo";

	/**
	 * 流程列表
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/processList")
	public String processList(Model model) {
		ProcessDefinitionQuery processDefinitionQuery = repositoryService
				.createProcessDefinitionQuery();
		// 获取最新版本的流程定义
		List<ProcessDefinition> processDefinitionList = processDefinitionQuery
				.latestVersion()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.orderByProcessDefinitionId().asc().list();

		model.addAttribute("processList", processDefinitionList);
		return "/workflow/processList";
	}

	/**
	 * 保存流程业务信息
	 * 
	 * @param leave
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/saveBusinessInfo")
	public String saveBusinessInfo(BusinessInfo businessInfo,
			@RequestParam("id") String id, HttpSession session) {
		// String userId = ((User) session.getAttribute("user")).getId();
		// leave.setApplyUserId(userId);
		// 存储表单信息
		// leaveMapper.insert(leave);
		// 启动用户信息
		// identityService.setAuthenticatedUserId(userId);
		// ProcessInstance processInstance =
		// runtimeService.startProcessInstanceByKey(BUSINESS_INFO_DEFINITION_KEY,
		// String.valueOf(leave.getId()));
		//修改完成后将is_report_back置为0,(0为非退回 1为退回)
		businessInfo.setIs_report_back(0);
		if (id == null || id.equals("")) {
			
			businessInfoMapper.insert(businessInfo);
			String userId = ((User) session.getAttribute("user")).getId();
			/*
			 * leave.setApplyUserId(userId); //存储表单信息 leaveMapper.insert(leave); //
			 * 启动用户信息
			 */
			Map<String, Object> vars = new HashMap<String, Object>();
			vars.put("before", "manager");
			ProcessInstance processInstance = null;
			try {
				identityService.setAuthenticatedUserId(userId);
				//启动流程同时存储变量map和businesskey
				processInstance = runtimeService.startProcessInstanceByKey(BUSINESS_INFO_DEFINITION_KEY, String.valueOf(businessInfo.getId()), vars);
			} finally {
				identityService.setAuthenticatedUserId(null);
			}
			session.setAttribute("processInstanceId", processInstance.getId());
		} else {
			businessInfoMapper.updateByPrimaryKeySelective(businessInfo);
		}
		String processInstanceId = (String) session
				.getAttribute("processInstanceId");
		Task task = taskService.createTaskQuery()
				.processInstanceId(processInstanceId).singleResult();
		Map<String, Object> maps = new HashMap<String, Object>();
		maps.put("businesskey", businessInfo.getId());
		taskService.complete(task.getId(), maps);
		return "redirect:/workflow/toDoProcessList";
	}

	/**
	 * 开启流程
	 * 
	 * @param leave
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/startProcess")
	public String startProcess(HttpSession session) {
		/*String userId = ((User) session.getAttribute("user")).getId();
		
		 * leave.setApplyUserId(userId); //存储表单信息 leaveMapper.insert(leave); //
		 * 启动用户信息
		 
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("before", "manager");
		ProcessInstance processInstance = null;
		try {
			identityService.setAuthenticatedUserId(userId);
			processInstance = runtimeService.startProcessInstanceByKey(
					BUSINESS_INFO_DEFINITION_KEY, vars);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		session.setAttribute("processInstanceId", processInstance.getId());*/
		return "redirect:/workflow/getBusinessForm";
	}

	/**
	 * 获取业务信息
	 * 
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/getBusinessForm")
	public String getBusinessForm(Model model) {
		// 在此处需要做一些查询，查出验收 人，负责人的下拉框选项
		List<User> list = identityService.createUserQuery().list();
		model.addAttribute("userList", list);
		return "/workflow/startBusiness";
	}

	/**
	 * 获取当前任务的表单
	 * 
	 * @param taskDefinitionKey
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/getTaskForm/{taskDefinitionKey}/{taskId}/{processInstanceId}")
	public String getTaskForm(
			@PathVariable("taskDefinitionKey") String taskDefinitionKey,
			@PathVariable("taskId") String taskId,
			@PathVariable("processInstanceId") String processInstanceId,
			Model model) throws Exception {
		ProcessInstance processInstance = runtimeService
				.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		// Leave leave = leaveMapper.selectByPrimaryKey(Integer
		// .valueOf(processInstance.getBusinessKey()));
		// model.addAttribute("leave", leave);
		HistoricVariableInstance historicVariableInstance = (HistoricVariableInstance) historyService
				.createHistoricVariableInstanceQuery()
				.processInstanceId(processInstanceId)
				.variableName("businesskey").singleResult();
		if (historicVariableInstance != null) {
			Integer businesskey = (Integer) historyService
					.createHistoricVariableInstanceQuery()
					.processInstanceId(processInstanceId)
					.variableName("businesskey").singleResult().getValue();
			BusinessInfo businessInfo = businessInfoMapper
					.selectByPrimaryKey(businesskey);
			model.addAttribute("taskId", taskId);
			model.addAttribute("businessInfo", businessInfo);
		}

		// 在此处需要做一些查询，查出验收 人，负责人的下拉框选项
		List<User> list = identityService.createUserQuery().list();
		model.addAttribute("userList", list);
		if ("planOfficer".equals(taskDefinitionKey)) {
			return "/workflow/startBusinessInfo";
		} else if ("businessManager".equals(taskDefinitionKey)) {
			return "/workflow/managerApprove";
		} else if ("viceManager".equals(taskDefinitionKey)) {
			return "/workflow/viceManagerApprove";
		}
		return "";
	}

	@RequestMapping(value = "/getFinishedTaskForm/{businessKey}")
	public String getFinishedTaskForm(
			@PathVariable("businessKey") int businessKey, Model model) {
		Leave leave = leaveMapper.selectByPrimaryKey(businessKey);
		model.addAttribute("leave", leave);
		return "/workflow/finishedTaskForm";
	}

	/**
	 * 完成经理审批
	 * 
	 * @param leave
	 * @param deptLeaderPass
	 * @param taskId
	 * @param session
	 * @return
	 */
	/*
	 * @RequestMapping(value = "/completeTaskManagerApprove")
	 * 
	 * @ResponseBody public String completeTaskManagerApprove(Leave leave,
	 * 
	 * @RequestParam("deptLeaderPass") String deptLeaderPass,
	 * 
	 * @RequestParam("taskId") String taskId, HttpSession session) { String
	 * userId = ((User) session.getAttribute("user")).getId(); // 更新leave表
	 * leaveMapper.updateByPrimaryKeySelective(leave);
	 * 
	 * Map<String, String> formProperties = new HashMap<String, String>();
	 * formProperties.put("deptLeaderPass", deptLeaderPass); try {
	 * identityService.setAuthenticatedUserId(userId);
	 * formService.submitTaskFormData(taskId, formProperties); } finally {
	 * identityService.setAuthenticatedUserId(null); } return "true"; }
	 */
	/**
	 * 完成经营业务经理审查
	 * 
	 * @param leave
	 * @param deptLeaderPass
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskManagerApprove")
	@ResponseBody
	public String completeTaskManagerApprove(BusinessInfo businessInfo,
			@RequestParam("deptLeaderPass") String deptLeaderPass,
			@RequestParam("taskId") String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		if(deptLeaderPass.equals("false")){
			businessInfo.setIs_report_back(1);
		}
		// 更新businessinfo表
		businessInfoMapper.updateByPrimaryKeySelective(businessInfo);

		Map<String, String> formProperties = new HashMap<String, String>();
		formProperties.put("deptLeaderPass", deptLeaderPass);
		try {
			identityService.setAuthenticatedUserId(userId);
			formService.submitTaskFormData(taskId, formProperties);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "true";
	}

	/**
	 * 完成经营副总审批
	 * 
	 * @param businessInfo
	 * @param deptLeaderPass
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskViceManagerApprove")
	@ResponseBody
	public String completeTaskViceManagerApprove(BusinessInfo businessInfo,
			@RequestParam("fuZhongPass") String fuZhongPass,
			@RequestParam("taskId") String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		if (fuZhongPass.equals("planOfficer")||fuZhongPass.equals("manager")) {
			businessInfo.setIs_report_back(1);
		}
		// 更新leave表
		businessInfoMapper.updateByPrimaryKeySelective(businessInfo);

		Map<String, String> formProperties = new HashMap<String, String>();
		formProperties.put("fuZhongPass", fuZhongPass);
		if (fuZhongPass.equals("planOfficer")) {
			formProperties.put("before", "fuzhong");
		}
		try {
			identityService.setAuthenticatedUserId(userId);
			formService.submitTaskFormData(taskId, formProperties);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "true";
	}

	/**
	 * 完成修改申请
	 * 
	 * @param leave
	 * @param reApply
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskModifyApply")
	public String completeTaskModifyApply(Leave leave,
			@RequestParam("reApply") String reApply,
			@RequestParam("taskId") String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		// 更新leave表
		leaveMapper.updateByPrimaryKeySelective(leave);

		Map<String, String> formProperties = new HashMap<String, String>();
		formProperties.put("reApply", reApply);
		try {
			identityService.setAuthenticatedUserId(userId);
			formService.submitTaskFormData(taskId, formProperties);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "/workflow/processList";
	}

	/**
	 * 销假
	 * 
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskReportBack")
	public String completeTaskReportBack(@RequestParam("taskId") String taskId,
			HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		try {
			identityService.setAuthenticatedUserId(userId);
			taskService.complete(taskId);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "/workflow/processList";
	}

	/**
	 * 待办任务列表
	 * 
	 * @param model
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/toDoProcessList")
	public String userToDoProcessList(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		// 获取当前用户为候选人的任务
		List<Task> tasks = taskService.createTaskQuery()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.taskCandidateUser(userId).list();
		// 获取已经分配给当前用户的任务
		List<Task> tasks1 = taskService.createTaskQuery()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.taskAssignee(userId).list();
		tasks.addAll(tasks1);
		model.addAttribute("tasks", tasks);

		// 根据待办中的processInstanceId获得ProcessInstance ProcessDefinition
		HashMap<String, HistoricProcessInstance> historicProcessInstances = new HashMap<String, HistoricProcessInstance>();
		HashMap<String, ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
		for (Task task : tasks) {
			HistoricProcessInstance historicProcessInstance = historyService
					.createHistoricProcessInstanceQuery()
					.processInstanceId(task.getProcessInstanceId())
					.singleResult();
			historicProcessInstances.put(task.getProcessInstanceId(),
					historicProcessInstance);

			ProcessDefinition processDefinition = repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionId(task.getProcessDefinitionId())
					.singleResult();
			processDefinitions.put(task.getProcessDefinitionId(),
					processDefinition);
		}
		model.addAttribute("historicProcessInstances", historicProcessInstances);
		model.addAttribute("processDefinitions", processDefinitions);

		return "/workflow/toDoProcessList";
	}

	/**
	 * 已退回的任务列表
	 * 
	 * @param model
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/reportBackProcessList")
	public String userReportBackProcessList(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();

		// model.addAttribute("businessInfo", businessInfo);
		// 此处为测试
		// 获取已经分配给当前用户的任务
		List<Task> tasks = new ArrayList<Task>();
		BusinessInfoExample example = new BusinessInfoExample();
		List<BusinessInfo> busList = businessInfoMapper
				.selectByExample(example);
		for (BusinessInfo info : busList) {
			if (info.getIs_report_back() == 1) {
				Integer buskey = info.getId();
				HistoricProcessInstance historicProcessInstance = historyService
						.createHistoricProcessInstanceQuery()
						.processInstanceBusinessKey(String.valueOf(buskey))
						.singleResult();
				String processId = historicProcessInstance.getId();
				List<Task> temp = taskService.createTaskQuery()
						.taskAssignee(userId).processInstanceId(processId)
						.list();
				List<Task> temp2 = taskService.createTaskQuery()
						.taskCandidateUser(userId).processInstanceId(processId)
						.list();
				tasks.addAll(temp);
				tasks.addAll(temp2);
			}
		}

		model.addAttribute("tasks", tasks);

		// 根据待办中的processInstanceId获得ProcessInstance ProcessDefinition
		HashMap<String, HistoricProcessInstance> historicProcessInstances = new HashMap<String, HistoricProcessInstance>();
		HashMap<String, ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
		for (Task task : tasks) {
			HistoricProcessInstance historicProcessInstance = historyService
					.createHistoricProcessInstanceQuery()
					.processInstanceId(task.getProcessInstanceId())
					.singleResult();
			historicProcessInstances.put(task.getProcessInstanceId(),
					historicProcessInstance);

			ProcessDefinition processDefinition = repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionId(task.getProcessDefinitionId())
					.singleResult();
			processDefinitions.put(task.getProcessDefinitionId(),
					processDefinition);
		}
		model.addAttribute("historicProcessInstances", historicProcessInstances);
		model.addAttribute("processDefinitions", processDefinitions);

		return "/workflow/toDoProcessList";
	}

	/**
	 * 签收流程
	 * 
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/claimProcess")
	public String claimProcess(String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		taskService.claim(taskId, userId);
		return "redirect:/workflow/toDoProcessList";
	}

	/**
	 * 运行中流程
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/runningProcessList")
	public String runningProcess(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		List<ProcessInstance> runningProcessList = runtimeService
				.createProcessInstanceQuery()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.involvedUser(userId).active().list();
		model.addAttribute("runningProcessList", runningProcessList);

		// 根据processDefinitionId获得 ProcessDefinition
		HashMap<String, ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
		for (ProcessInstance processInstance : runningProcessList) {
			ProcessDefinition processDefinition = repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionId(
							processInstance.getProcessDefinitionId())
					.singleResult();
			processDefinitions.put(processInstance.getProcessDefinitionId(),
					processDefinition);
		}
		model.addAttribute("processDefinitions", processDefinitions);
		return "/workflow/runningProcessList";
	}

	/**
	 * 显示流程的详细历史
	 * 
	 * @param processInstanceId
	 * @param model
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/runningProcessHistory/{processInstanceId}")
	public String runningProcessHistory(
			@PathVariable("processInstanceId") String processInstanceId,
			Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();

		List<HistoricTaskInstance> historicTasks = historyService
				.createHistoricTaskInstanceQuery()
				.processInstanceId(processInstanceId).list();
		model.addAttribute("historicTasks", historicTasks);

		return "/workflow/processHistory";
	}

	/**
	 * 已完成的流程实例
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/finishedProcessList")
	public String finished(Model model, HttpServletRequest request,
			HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		List<HistoricProcessInstance> finishedProcessList = historyService
				.createHistoricProcessInstanceQuery()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.startedBy(userId).orderByProcessInstanceEndTime().desc()
				.finished().list();
		model.addAttribute("finishedProcessList", finishedProcessList);

		// 根据processDefinitionId获得 ProcessDefinition
		HashMap<String, ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
		for (HistoricProcessInstance historicProcessInstance : finishedProcessList) {
			ProcessDefinition processDefinition = repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionId(
							historicProcessInstance.getProcessDefinitionId())
					.singleResult();
			processDefinitions.put(
					historicProcessInstance.getProcessDefinitionId(),
					processDefinition);
		}
		model.addAttribute("processDefinitions", processDefinitions);
		return "/workflow/finishedProcessList";
	}

	/**
	 * 获取当前流程实例的流程图
	 * 
	 * @param processInstanceId
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/image/{processInstanceId}")
	public void getImage(
			@PathVariable("processInstanceId") String processInstanceId,
			HttpServletResponse response) throws Exception {
		Command<InputStream> cmd = new HistoryProcessInstanceDiagramCmd(
				processInstanceId);

		InputStream is = managementService.executeCommand(cmd);
		response.setContentType("image/png");

		int len = 0;
		byte[] b = new byte[1024];

		while ((len = is.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 获取流程定义图
	 * 
	 * @param processDefinitionId
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/processDefinitionImage/{processDefinitionId}")
	public void getProcessDefinitionImage(
			@PathVariable("processDefinitionId") String processDefinitionId,
			HttpServletResponse response) throws Exception {
		ProcessDefinition processDefinition = repositoryService
				.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).singleResult();
		InputStream resourceAsStream = repositoryService.getResourceAsStream(
				processDefinition.getDeploymentId(),
				processDefinition.getDiagramResourceName());
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 已办任务
	 * 
	 * @param model
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/processedTaskList")
	public String processedTaskList(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		List<HistoricTaskInstance> processedTasks = historyService
				.createHistoricTaskInstanceQuery()
				.processDefinitionKey(BUSINESS_INFO_DEFINITION_KEY)
				.taskAssignee(userId).finished().list();
		model.addAttribute("processedTasks", processedTasks);
		// 根据processInstanceId获得processInstace
		HashMap<String, HistoricProcessInstance> processInstances = new HashMap<String, HistoricProcessInstance>();
		for (HistoricTaskInstance processedTask : processedTasks) {
			HistoricProcessInstance historicProcessInstance = historyService
					.createHistoricProcessInstanceQuery()
					.processInstanceId(processedTask.getProcessInstanceId())
					.singleResult();
			processInstances.put(processedTask.getProcessInstanceId(),
					historicProcessInstance);
		}
		model.addAttribute("processInstances", processInstances);
		return "/workflow/processedTaskList";
	}

	/**
	 * 撤销已办任务
	 * 
	 * @param taskId
	 * @return
	 */
	@RequestMapping(value = "/callBack/{taskId}")
	@ResponseBody
	public String callBack(@PathVariable("taskId") String taskId) {
		Command<Integer> cmd = new WithdrawTaskCmd(taskId);
		return managementService.executeCommand(cmd).toString();
	}

}
